﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.Data;

using agvcontroller.Driver;
using agvcontroller.Common;
using agvcontroller.Common.DataBase;
using agvcontroller.Log;

namespace agvcontroller.Control
{
    public enum enumTowerLampState
    {
        NOJOB,
        RUNJOB,
        READYJOB,
    }

    public enum enumTowerLampSignal
    {
        ON,
        OFF,
        FLICK,
    }

    public enum enumBuzzerState
    {
        NONE,
        CH1,
        CH2,
        CH3,
        CH4,
    }

    public enum enumMelodyState
    {
        NONE,
        CH1,
        CH2,
        CH3,
        CH4,
    }

    public delegate void deleTerminalConnection(object sender , enumConnect connection);
    public delegate void deleTerminalRequestJob(object sender, int jobNo);
    public delegate void deleTerminalCancelJob(object sender, int jobNo);

    public class CTerminal
    {
        public event deleTerminalConnection onConnect;
        public event deleTerminalRequestJob onRequestJob;
        public event deleTerminalCancelJob onCancelJob;

        public int ID
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public bool Use
        {
            get;
            set;
        }

        public int TerminalNodeID
        {
            get;
            set;
        }

        public enumConnect Connection
        {
            get;
            set;
        }

        public int Port
        {
            get;
            set;
        }

        public IPAddress TerminalIP
        {
            get;
            set;
        }

        public IPAddress AGVCIP
        {
            get;
            set;
        }

        List<bool> RequestJobList = new List<bool>();
        List<bool> RequestJobLampList = new List<bool>();
        List<bool> CancelJobList = new List<bool>();
        List<int> JobNode = new List<int>();

        CTowerLamp TowerLamp = new CTowerLamp();
        CBuzzer Buzzer = new CBuzzer();
        CMelody Melody = new CMelody();

        CTerminalSocketDriver SocketDriver;
        Logger Log;

        public CTerminal(string name)
        {
            Name = name;
            Log = new Logger(this.Name);
        }

        public int InitModule()
        {
            RegistEvent();

            SocketDriver = new CTerminalSocketDriver(AGVCIP, TerminalIP, Port);

            if (SocketDriver.StartListen() == 0)
                Connection = enumConnect.CONNECTION;

            return CReturnCode.SUCCESS;
        }

        void RegistEvent()
        {
            SocketDriver.onConnect+=new deleTerminalSocketReportConnect(SocketDriver_onConnect);
            SocketDriver.onRequestJob += new Driver.deleTerminalRequestJob(SocketDriver_onRequestJob);
            SocketDriver.onCancelJob += new Driver.deleTerminalCancelJob(SocketDriver_onCancelJob);
        }

        void SocketDriver_onCancelJob(object sender, int jobNo)
        {
            if (onCancelJob != null)
                onCancelJob(this, jobNo);
            Log.Info(string.Format("Cancel Job : {0}", jobNo));
        }

        void SocketDriver_onRequestJob(object sender, int jobNo)
        {
            if (onRequestJob != null)
                onRequestJob(this, jobNo);

            Log.Info(string.Format("Request Job : {0}", jobNo));
        }

        void SocketDriver_onConnect(object sender, enumConnect connect)
        {
            Connection = enumConnect.CONNECTION;

            if (onConnect != null)
                onConnect(this, enumConnect.CONNECTION);

            Log.Info(string.Format("Connted"));

        }

        public void SetRequestJobButtonLamp(int jobNo, bool onoff)
        {
        }

        public void SetCancelJobButtonLamp(int jobNo, bool onoff)
        {
        }

        public void SetTowerLamp(enumTowerLampState towerlampstate)
        {
            TowerLamp.SetTowerLamp(towerlampstate);
        }

        public void SetBuzzer(enumBuzzerState buzzerstate)
        {
            Buzzer.SetBuzzer(buzzerstate);
        }

        public void SetMelody(enumMelodyState melodystate)
        {
            Melody.SetMelody(melodystate);
        }

        public int GetJobNodeID(int jobNo)
        {
            return JobNode[jobNo];
        }
    }

    public class CTerminalDic : Dictionary<int, CTerminal>
    {
        CAGVCDB AGVCDB;
        Logger Log;

        private static CTerminalDic uniqueInstance;

        public static CTerminalDic getInstance()
        {
            if (uniqueInstance == null)
            {
                uniqueInstance = new CTerminalDic();
            }
            return uniqueInstance;
        }

        public int InitMoudle()
        {
            int resurncode = CReturnCode.SUCCESS;
            
            foreach (KeyValuePair<int, CTerminal> vehicle in this)
            {
                resurncode = vehicle.Value.InitModule();
            }

            return CReturnCode.SUCCESS;
        }

        public CTerminalDic()
        {
            Log = new Logger("TerminalDic");

            GetDataFromDB();
        }

        public int AddVehicle(CTerminal terminal)
        {
            this.Add(terminal.ID, terminal);

            return CReturnCode.SUCCESS;
        }

        virtual public int GetDataFromDB()
        {
            AGVCDB = CAGVCDB.getInstance();
            DataTable table = AGVCDB.AGVCDataSet.Tables["TerminalList"];
            CTerminal terminal;

            try{
                    foreach(DataRow row in table.Rows)
                    {
                        terminal = new CTerminal(Convert.ToString(row["Name"]));
                        terminal.ID = Convert.ToInt32(row["ID"]);
                        
                        terminal.Port = Convert.ToInt32(row["Port"]);
                        terminal.AGVCIP = IPAddress.Parse(Convert.ToString(row["AGVCIP"]));
                        terminal.TerminalIP = IPAddress.Parse(Convert.ToString(row["TerminalIP"]));

                        terminal.InitModule();

                        this.Add(terminal.ID, terminal);
                    }
                }
            catch (Exception ex)
            {
                return CReturnCode.ERR_DATA_ACQUIRING_FAIL;
                Log.Exception(string.Format("{0},{1}", ex.Message, ex.StackTrace));
            }
            return CReturnCode.SUCCESS;
        }

        virtual public void SetDataToDB()
        {
        }
    }

    public class CTowerLamp
    {
        enumTowerLampSignal RED;
        enumTowerLampSignal GREEN;
        enumTowerLampSignal BLUE;

        public void SetTowerLamp(enumTowerLampState towerlampstate)
        { 
        
        }
    }

    public class CBuzzer
    {
        enumBuzzerState BuzzerCH;

        public void SetBuzzer(enumBuzzerState buzzerstate)
        {
            BuzzerCH = buzzerstate;
        }
    }

    public class CMelody
    {
        enumMelodyState MelodyCH;

        public void SetMelody(enumMelodyState melodystate)
        {
            MelodyCH = melodystate;
        }
    }
}
